package com.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/*
 * 该方法接收两个参数，一个是复制的源对象——要复制的对象，一个是复制的目标对象——对象副本。
 * 当然这个方法也可以在两个不同对象间使用，这时候只要目标对象和对象具有一个或多个相同类型及名称的属性，那么就会把源对象的属性值赋给目标对象的属性
 */
public class CopyUtil {

	public static <T> T getBean(T TargetBean, T SourceBean) throws Exception {
		if (TargetBean == null)
			return null;
		Field[] tFields = TargetBean.getClass().getDeclaredFields();
		Field[] sFields = SourceBean.getClass().getDeclaredFields();
		try {
			for (Field field : tFields) {
				String fieldName = field.getName();
				if (fieldName.equals("serialVersionUID"))
					continue;
				if (field.getType() == Map.class)
					continue;
				if (field.getType() == Set.class)
					continue;
				if (field.getType() == List.class)
					continue;
				for (Field sField : sFields) {
					if (!sField.getName().equals(fieldName)) {
						continue;
					}
					Class type = field.getType();
					String setName = getSetMethodName(fieldName);
					Method tMethod = TargetBean.getClass().getMethod(setName, new Class[] { type });
					String getName = "";
					if(field.getType() == boolean.class || field.getType() == Boolean.class){
						getName = getIsMethodName(fieldName);
					}else{
						getName = getGetMethodName(fieldName);
					}
					Method sMethod = SourceBean.getClass().getMethod(getName, null);
					Object setterValue = sMethod.invoke(SourceBean, null);
					tMethod.invoke(TargetBean, new Object[] { setterValue });
				}
			}
		} catch (Exception e) {
			throw new Exception("设置参数信息发生异常", e);
		}
		return TargetBean;
	}
	
	
	public static <T> T Copy(T target, T source) throws Exception {
		if (target == null)
			return null;
		Field[] tFields = target.getClass().getDeclaredFields();
		Field[] sFields = source.getClass().getDeclaredFields();
		try {
			for (Field field : tFields) {
				String fieldName = field.getName();
				if (fieldName.equals("serialVersionUID"))
					continue;
				
				if(field.getType().isPrimitive() 
						|| field.getType() == String.class 
						|| field.getType() == Boolean.class
						|| field.getType() == Integer.class
						|| field.getType() == Long.class
						|| field.getType() == Float .class
						|| field.getType() == Double.class
						|| field.getType() == Date.class
						){
					for (Field sField : sFields) {
						if (!sField.getName().equals(fieldName)) {
							continue;
						}
						Class type = field.getType();
						String setName = getSetMethodName(fieldName);
						Method tMethod = target.getClass().getMethod(setName, new Class[] { type });
						String getName = "";
						if(field.getType() == boolean.class){
							getName = getIsMethodName(fieldName);
						}else{
							getName = getGetMethodName(fieldName);
						}
						Method sMethod = source.getClass().getMethod(getName, null);
						Object setterValue = sMethod.invoke(source, null);
						tMethod.invoke(target, new Object[] { setterValue });
					}
				}
				
			}
		} catch (Exception e) {
			throw new Exception("设置参数信息发生异常", e);
		}
		return target;
	}

	private static String getGetMethodName(String fieldName) {
		fieldName = replaceFirstCharToUpper(fieldName);
		return "get" + fieldName;
	}
	
	private static String getIsMethodName(String fieldName) {
		fieldName = replaceFirstCharToUpper(fieldName);
		return "is" + fieldName;
	}

	private static String getSetMethodName(String fieldName) {
		fieldName = replaceFirstCharToUpper(fieldName);
		return "set" + fieldName;
	}

	private static String replaceFirstCharToUpper(String fieldName) {
		char[] chars = new char[1];
		chars[0] = fieldName.charAt(0);
		String temp = new String(chars);
		if (chars[0] >= 'a' && chars[0] <= 'z') {
			fieldName = fieldName.replaceFirst(temp, temp.toUpperCase());
		}
		return fieldName;
	}
}